# -*- coding: utf-8 -*-
"""
简化测试版本 - 测试核心语音对话功能

功能说明:
- 测试GPT API调用功能
- 测试TTS音频合成功能
- 验证API响应格式
- 模拟WebSocket消息流程

使用场景:
- 开发阶段功能验证
- 环境配置测试
- API接口调试
"""

import base64
import hashlib
import hmac
import json
import queue
import threading
import time
from datetime import datetime
from urllib.parse import quote, urlencode
from wsgiref.handlers import format_date_time

import websocket
import pyaudio
from websocket import create_connection
from openai import OpenAI

# ========= 配置参数 ========= #
# 讯飞API配置 - 语音识别(ASR)
XF_APPID_ASR = "9646138c"
XF_APIKEY_ASR = "82adf64eb83cf7b9ec6f4ae215943e0d"

# 讯飞API配置 - 语音合成(TTS)
XF_APPID_TTS = "9646138c"
XF_APIKEY_TTS = "ea89fb89877aded124af01b32cb14324"
XF_SECRET_TTS = "MzlhYmQyMjI5ODYzYzU2ODM2YWMxYWNk"

# ========= GPT 流式处理 ========= #
def gpt_stream_to_queue(q: queue.Queue, user_prompt: str, system_prompt: str = None):
    """
    GPT 流式输出 → 按规则切块 → 入队
    
    参数:
        q: 队列对象，用于存储GPT输出的文本块
        user_prompt: 用户输入的文本
        system_prompt: 系统提示词，用于设定AI角色
    
    功能:
        - 调用OpenAI GPT API进行对话生成
        - 将GPT的流式输出按句子或标点符号切块
        - 将切块后的文本放入队列中
    """
    # 初始化OpenAI客户端
    client = OpenAI(
        api_key="sk-BPVBVZQbXHrUH6b540DbE34b4c71479f9dD4106dCc29C021",
        base_url="https://api.pumpkinaigc.online/v1"
    )
    
    # 构建对话消息列表
    messages = [
        {"role": "system", "content": system_prompt or "You are chatting with me, your name is xiaoxi. Only reply in English."},
        {"role": "user", "content": user_prompt}
    ]
    
    # 调用GPT API进行流式对话
    resp = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        stream=True
    )

    # 处理流式响应
    buffer = ""
    for part in resp:
        delta = part.choices[0].delta
        if not getattr(delta, "content", None):
            continue
        token = delta.content
        buffer += token
        # 当缓冲区达到80字符或遇到句子结束标点时，将文本块放入队列
        if len(buffer) >= 80 or buffer.endswith(('.', '!', '?', '。', '！', '？')):
            q.put(buffer)
            buffer = ""
    # 处理剩余的文本
    if buffer.strip():
        q.put(buffer)
    q.put(None)  # 发送结束信号

# ========= 讯飞 TTS 语音合成 ========= #
class Ws_Param:
    """讯飞TTS WebSocket参数类"""
    def __init__(self, appid, apikey, apisecret, text):
        """
        初始化TTS参数
        
        参数:
            appid: 讯飞应用ID
            apikey: 讯飞API密钥
            apisecret: 讯飞API密钥
            text: 要合成的文本内容
        """
        self.APPID = appid
        self.APIKey = apikey
        self.APISecret = apisecret
        self.Text = text
        # 通用参数
        self.CommonArgs = {"app_id": self.APPID}
        # 业务参数 - 音频格式配置
        self.BusinessArgs = {
            "aue": "raw",  # 音频编码格式
            "auf": "audio/L16;rate=16000",  # 音频采样率
            "vcn": "x4_yezi",  # 发音人
            "tte": "utf8"  # 文本编码格式
        }
        # 数据参数
        self.Data = {
            "status": 2,  # 状态码
            "text": str(base64.b64encode(self.Text.encode('utf-8')), "utf8")  # base64编码的文本
        }

    def create_url(self):
        """
        生成讯飞TTS WebSocket连接URL
        
        返回:
            str: 包含认证信息的WebSocket URL
        """
        url = "wss://tts-api.xfyun.cn/v2/tts"
        now = datetime.now()
        date = format_date_time(time.mktime(now.timetuple()))
        
        # 生成签名
        sig_origin = f"host: ws-api.xfyun.cn\n" \
                     f"date: {date}\n" \
                     f"GET /v2/tts HTTP/1.1"
        sign = hmac.new(self.APISecret.encode(), sig_origin.encode(),
                        digestmod=hashlib.sha256).digest()
        sign = base64.b64encode(sign).decode()
        
        # 生成认证信息
        auth_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", ' \
                      f'headers="host date request-line", signature="{sign}"'
        authorization = base64.b64encode(auth_origin.encode()).decode()
        
        # 返回完整的URL
        return url + "?" + urlencode({
            "authorization": authorization,
            "date": date,
            "host": "ws-api.xfyun.cn"
        })

def tts_synthesize(text):
    """
    TTS 合成并返回音频数据
    
    参数:
        text: 要合成的文本内容
    
    返回:
        str: base64编码的音频数据，失败时返回None
    """
    audio_chunks = []  # 存储音频数据块
    done_flag = threading.Event()  # 完成标志

    def on_message(ws, message):
        """WebSocket消息处理函数"""
        msg = json.loads(message)
        audio_bytes = base64.b64decode(msg["data"]["audio"])
        audio_chunks.append(audio_bytes)
        if msg["data"]["status"] == 2:  # 合成完成
            ws.close()

    def on_error(ws, error):
        """WebSocket错误处理函数"""
        print("TTS ws error:", error)

    def on_close(ws, close_status_code, close_msg):
        """WebSocket关闭处理函数"""
        done_flag.set()

    def on_open(ws):
        """WebSocket连接建立处理函数"""
        def run(*_):
            req = {
                "common": wsParam.CommonArgs,
                "business": wsParam.BusinessArgs,
                "data": wsParam.Data
            }
            ws.send(json.dumps(req))
        threading.Thread(target=run).start()

    # 创建WebSocket参数
    wsParam = Ws_Param(XF_APPID_TTS, XF_APIKEY_TTS, XF_SECRET_TTS, text)
    websocket.enableTrace(False)
    
    # 创建WebSocket连接
    ws = websocket.WebSocketApp(
        wsParam.create_url(),
        on_open=on_open,
        on_message=on_message,
        on_error=on_error,
        on_close=on_close
    )
    
    # 运行WebSocket连接
    ws.run_forever(sslopt={"cert_reqs": 0})
    done_flag.wait()  # 等待合成完成
    
    # 合并所有音频块并返回base64编码
    if audio_chunks:
        combined_audio = b''.join(audio_chunks)
        return base64.b64encode(combined_audio).decode()
    return None

def test_chat_api():
    """
    测试聊天API功能
    
    功能:
        - 模拟完整的聊天流程
        - 测试GPT API调用
        - 测试TTS音频合成
        - 验证API响应格式
    """
    print("=== 测试聊天API功能 ===")
    
    # 测试参数
    system_prompt = "You are chatting with me, your name is xiaoxi. Only reply in English."
    user_prompt = "Hello, how are you?"
    
    print(f"系统提示词: {system_prompt}")
    print(f"用户输入: {user_prompt}")
    
    try:
        # 1. GPT处理
        print("\n1. 调用GPT生成回复...")
        q = queue.Queue()
        gpt_stream_to_queue(q, user_prompt, system_prompt)
        
        # 收集GPT回复
        gpt_response = ""
        while True:
            chunk = q.get()
            if chunk is None:
                break
            gpt_response += chunk
        
        print(f"GPT回复: {gpt_response}")
        
        if not gpt_response.strip():
            print("❌ GPT未生成有效回复")
            return
        
        # 2. TTS合成
        print("\n2. 调用TTS合成音频...")
        audio_data = tts_synthesize(gpt_response)
        
        if audio_data:
            print(f"✅ TTS合成成功，音频数据长度: {len(audio_data)}")
            
            # 模拟API响应
            response = {
                "success": True,
                "message": gpt_response,
                "audio_data": audio_data
            }
            
            print("\n=== API响应示例 ===")
            print(json.dumps(response, ensure_ascii=False, indent=2))
            
        else:
            print("❌ TTS合成失败")
            
    except Exception as e:
        print(f"❌ 测试失败: {str(e)}")

def test_websocket_flow():
    """
    测试WebSocket流程
    
    功能:
        - 模拟WebSocket消息流程
        - 展示消息类型和格式
        - 验证消息结构
    """
    print("\n=== 测试WebSocket流程 ===")
    
    # 模拟WebSocket消息流程
    messages = [
        {"type": "status", "message": "ASR连接成功，可以开始说话"},
        {"type": "recognition", "text": "你好，我是用户"},
        {"type": "gpt_response", "text": "Hello! I'm xiaoxi, nice to meet you!"},
        {"type": "audio", "data": "base64_audio_data_here"},
        {"type": "complete", "message": "对话完成"}
    ]
    
    for msg in messages:
        print(f"WebSocket消息: {json.dumps(msg, ensure_ascii=False)}")

# 主程序入口
if __name__ == "__main__":
    print("🚀 开始测试语音对话系统核心功能")
    print("=" * 50)
    
    # 测试聊天API
    test_chat_api()
    
    # 测试WebSocket流程
    test_websocket_flow()
    
    print("\n" + "=" * 50)
    print("✅ 测试完成！")
    print("\n📝 说明:")
    print("1. 这个测试验证了核心的GPT和TTS功能")
    print("2. 如果测试成功，说明后端API可以正常工作")
    print("3. 前端可以基于这些功能进行开发") 